package pv;

import java.util.concurrent.TimeUnit;

/**
 * 生产者 - 消费者
 * <p>
 * 生产者生产产品放入缓冲区
 * 消费者从缓冲区消费产品
 * 缓冲区是临界资源，各个进程需要互斥访问
 * 生产者只有在缓冲区有剩余空间才能往缓冲区放入产品
 * 消费者只有在缓冲区有产品才能从缓冲区获取产品
 * 当缓冲区没有剩余空间时, 生产者需要等待消费者消费
 * 当缓冲区中没有产品时，消费者需要等待生产者生产产品
 * </p>
 *
 * @author yezh
 * @date 2024/7/3 16:56
 */
public class ProductAConsum {

    private static final Semaphore MUTEX = new Semaphore(1);
    private static final Semaphore EMPTY = new Semaphore(5);
    private static final Semaphore FULL = new Semaphore(0);

    public static void main(String[] args) {
        new Thread(() -> {
            try {
                while (true) product();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();

        new Thread(() -> {
            try {
                while (true) consume();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();

        new Thread(() -> {
            try {
                while (true) consume();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();

    }

    public static void product() throws InterruptedException {
        EMPTY.p();
        MUTEX.p();
        System.out.println(Thread.currentThread().getName() + " 生产产品");
        MUTEX.v();
        FULL.v();
        TimeUnit.SECONDS.sleep(2);
    }

    public static void consume() throws InterruptedException {
        FULL.p();
        MUTEX.p();
        System.out.println(Thread.currentThread().getName() + " 消费产品");
        MUTEX.v();
        EMPTY.v();
        TimeUnit.SECONDS.sleep(2);
    }

}
